﻿using Lhz.Sc.Business;
using Lhz.Sc.Entity.Exception;
using Lhz.Sc.Entity.Interface;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;

namespace Lhz.Sc.Test.LhzScBusiness
{
    [TestClass]
    public class UnitTestServiceCenter
    {
        private UserProxy uo = new UserProxy();
        private LogProxy lo = new LogProxy();
        private ServiceProxy so = new ServiceProxy();

        [TestMethod]
        public void ServiceCenterBusinessTestMethodLogin()
        {
            var user = uo.Query().Where(r => !r.IsAdmin).First();
            var sco = new ServiceCenterOperation();
            sco.Login(user.Username, user.Password);
            try
            {
                sco.Login(user.Username, user.Password + Guid.NewGuid());
            }
            catch (Exception e)
            {
                Assert.AreEqual(e.GetType(), typeof(UsernameOrPasswordErrorException));
            }
        }

        [TestMethod]
        public void ServiceCenterBusinessTestMethodInvokeWithWrongApplicationNo()
        {
            var testIp = Guid.NewGuid().ToString();
            var operationNo = "query";

            lo.Delete(lo.Query());
            var logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);

            var user = uo.Query().First(r => !r.IsAdmin);
            var service = so.Query().First(r => r.Application.No == "Sc" && r.No == "user");
            var application = service.Application;
            var sco = new ServiceCenterOperation();
            var ia = new InvokeArgument()
            {
                ApplicationNo = application.No + Guid.NewGuid(),
                ServiceNo = service.No,
                OperationNo = operationNo
            };
            try
            {
                sco.JsonInvoke(ia, user, testIp);
            }
            catch (Exception e)
            {
                Assert.AreEqual(e.InnerException.GetType(), typeof(ApplicationNoNotFoundException));
            }

            logs = lo.Query();
            Assert.AreEqual(logs.Count, 1);
            var log = logs.First();
            Assert.AreEqual(log.UserGuid, user.Guid);
            Assert.AreEqual(log.Ip, testIp);
            Assert.IsTrue(log.InvokeResult.Contains(service.No));
            Assert.IsTrue(log.InvokeResult.Contains(operationNo));

            lo.Delete(log);
            logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);
        }

        [TestMethod]
        public void ServiceCenterBusinessTestMethodInvokeWithWrongServiceNo()
        {
            var testIp = Guid.NewGuid().ToString();
            var operationNo = "query";

            lo.Delete(lo.Query());
            var logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);

            var user = uo.Query().First(r => !r.IsAdmin);
            var service = so.Query().First(r => r.Application.No == "Sc" && r.No == "user");
            var application = service.Application;
            var sco = new ServiceCenterOperation();
            var ia = new InvokeArgument()
            {
                ApplicationNo = application.No,
                ServiceNo = service.No + Guid.NewGuid(),
                OperationNo = operationNo
            };
            try
            {
                sco.JsonInvoke(ia, user, testIp);
            }
            catch (Exception e)
            {
                Assert.AreEqual(e.InnerException.GetType(), typeof(ServiceNoNotFoundException));
            }

            logs = lo.Query();
            Assert.AreEqual(logs.Count, 1);
            var log = logs.First();
            Assert.AreEqual(log.UserGuid, user.Guid);
            Assert.AreEqual(log.Ip, testIp);
            Assert.IsTrue(log.InvokeResult.Contains(service.No));
            Assert.IsTrue(log.InvokeResult.Contains(operationNo));

            lo.Delete(log);
            logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);
        }

        [TestMethod]
        public void ServiceCenterBusinessTestMethodInvokeWithWrongOperationNo()
        {
            var testIp = Guid.NewGuid().ToString();
            var operationNo = "query";

            lo.Delete(lo.Query());
            var logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);

            var user = uo.Query().First(r => !r.IsAdmin);
            var service = so.Query().First(r => r.Application.No == "Sc" && r.No == "user");
            var application = service.Application;
            var sco = new ServiceCenterOperation();
            var ia = new InvokeArgument()
            {
                ApplicationNo = application.No,
                ServiceNo = service.No,
                OperationNo = operationNo + Guid.NewGuid()
            };
            try
            {
                sco.JsonInvoke(ia, user, testIp);
            }
            catch (Exception e)
            {
                Assert.AreEqual(e.InnerException.GetType(), typeof(OperationNoNotFoundException));
            }

            logs = lo.Query();
            Assert.AreEqual(logs.Count, 1);
            var log = logs.First();
            Assert.AreEqual(log.UserGuid, user.Guid);
            Assert.AreEqual(log.Ip, testIp);
            Assert.IsTrue(log.InvokeResult.Contains(service.No));
            Assert.IsTrue(log.InvokeResult.Contains(operationNo));

            lo.Delete(log);
            logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);
        }

        [TestMethod]
        public void ServiceCenterBusinessTestMethodInvoke()
        {
            var testIp = Guid.NewGuid().ToString();
            var operationNo = "query";

            lo.Delete(lo.Query());
            var logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);

            var user = uo.Query().First(r => r.Username == "liuhongzhe");
            var service = so.Query().First(r => r.Application.No == "Sc" && r.No == "user");
            var application = service.Application;
            var sco = new ServiceCenterOperation();
            var ia = new InvokeArgument()
            {
                ApplicationNo = application.No,
                ServiceNo = service.No,
                OperationNo = operationNo,
                Arguments = new string[] { null }
            };
            sco.JsonInvoke(ia, user, testIp);

            logs = lo.Query();
            Assert.AreEqual(logs.Count, 1);
            var log = logs.First();
            Assert.AreEqual(log.UserGuid, user.Guid);
            Assert.AreEqual(log.Ip, testIp);
            Assert.IsTrue(log.InvokeResult.Contains(service.No));
            Assert.IsTrue(log.InvokeResult.Contains(operationNo));

            lo.Delete(log);
            logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);
        }
    }
}
